package com.mk.service.web;

import act.controller.Controller;
import act.event.ActEvent;
import act.event.On;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.mk.domain.*;
import com.mk.enums.GlobalValues;
import com.mk.enums.PayValues;
import com.mk.exception.UserException;
import com.mk.interceptor.ITranslate;
import com.mk.util.MapUtil;
import com.mk.util.S2;
import com.mk.util.pay.PayUtils;
import org.osgl.mvc.annotation.GetAction;
import org.osgl.mvc.annotation.PostAction;
import org.osgl.mvc.annotation.PutAction;
import org.osgl.mvc.annotation.With;
import org.osgl.util.C;
import org.osgl.util.S;

import javax.inject.Inject;
import java.math.BigDecimal;
import java.util.*;

@Controller("tOrder")
public class TOrderService extends BaseWebService {

    @Inject
    private TOrder.Mapper tOrderMapper;
    @Inject
    private TOrderDetail.Mapper tOrderDetailMapper;
    @Inject
    private ZMbAddress.Mapper zMbAddressMapper;
    @Inject
    private TProductSpec.Mapper tProductSpecMapper;
    @Inject
    private TCart.Mapper tCartMapper;
    @Inject
    private CpConfig.Mapper cpConfigMapper;
    @Inject
    private TMbOrderFlow.Mapper tMbOrderFlowMapper;

    /**
     * 获取统一折扣
     * @return
     */
    public BigDecimal getDiscount(){
        CpConfig config = cpConfigMapper.single(GlobalValues.CP_CONFIG_DISCOUNT.value());
        BigDecimal tempD = BigDecimal.ONE;
        if(config!=null){
            tempD = new BigDecimal(config.getCfvalue());
        }
        return tempD;
    }
    /**
     * 下单
     *
     * @return
     */
    @PostAction("addOrder.json")
    @With({WbILogin.class, ITranslate.class})
    public Map<String, Object> addOrder(String paytype, String addid, List<TCart> list, String leaveword) {
        ZMbAddress address = zMbAddressMapper.single(addid);
        TOrder order = new TOrder();
        order.setOrderid(S2.buildOrderId("OS"));
        order.setMid(me.getMid());
        order.setOrderstatus(GlobalValues.ORDER_STATUS_0.value());

        order.setUnderdate(DateUtil.now());
        order.setRecipients(address.getRecipients());
        order.setCellphone(address.getCellphone());
        order.setProvince(address.getProvince());
        order.setCity(address.getCity());
        order.setArea(address.getArea());
        order.setAdress(address.getAdress());
        order.setPaynumber(S2.buildOrderId("PAY"));
        order.setPaytype(paytype);
        order.setLeaveword(leaveword);
        order.setPmid(me.getPmid());
        Map<String, Object> map = addOrderDetail(order, list);
        order.setDiscount(MapUtil.getDg(map, "discount", BigDecimal.ONE));
        order.setOriginalprice(MapUtil.getDg(map, "originaltotal", BigDecimal.ZERO));
        order.setOrderamount(MapUtil.getDg(map, "total", BigDecimal.ZERO));
        tOrderMapper.insertTemplate(order);
        return C.Map("order", order);
    }

    /**
     * 组装订单详情
     *
     * @param order
     * @param cartList
     * @return
     */
    private Map<String, Object> addOrderDetail(TOrder order, List<TCart> cartList) {
        BigDecimal tempD = getDiscount();
        final BigDecimal discount = tempD;
        List<String> psids = new ArrayList<>();
        List<String> cartids = new ArrayList<>();
        cartList.forEach(cart -> {
            if (S.isNotBlank(cart.getCartid())) {
                cartids.add(cart.getCartid());
            }
            psids.add(cart.getPsid());
        });

        List<Map<String, Object>> listProduct = tProductSpecMapper.queryProductSecByPsids(psids);
        List<TOrderDetail> details = new ArrayList<>();
        Map<String, Object> result = new HashMap<>();
        result.put("total", BigDecimal.ZERO);
        result.put("discount", tempD);
        result.put("originaltotal", BigDecimal.ZERO);
        listProduct.forEach(map -> {
            TOrderDetail detail = new TOrderDetail();
            detail.setOdid(S2.buildOrderId("OD"));
            detail.setOrderid(order.getOrderid());
            detail.setOdstatus(order.getOrderstatus());
            detail.setMid(me.getMid());
            detail.setBrid(MapUtil.getStr(map, "brid"));
            detail.setPdid(MapUtil.getStr(map, "pdid"));
            detail.setPsid(MapUtil.getStr(map, "psid"));
            detail.setPsprice(MapUtil.getDg(map, "psprice", BigDecimal.ZERO));
            TCart cart = cartList.stream().filter(d -> S.eq(d.getPsid(), MapUtil.getStr(map, "psid"))).findFirst().get();
            detail.setDiscount(discount);
            detail.setDetailrnumber(cart.getCartnumber());
            detail.setDetailtotal(new BigDecimal(cart.getCartnumber()).multiply(detail.getPsprice()).multiply(discount));
            detail.setOriginalprice(new BigDecimal(cart.getCartnumber()).multiply(detail.getPsprice()));
            details.add(detail);
            result.put("total", MapUtil.getDg(result, "total", BigDecimal.ZERO).add(detail.getDetailtotal()));
            result.put("originaltotal", MapUtil.getDg(result, "originaltotal", BigDecimal.ZERO).add(detail.getOriginalprice()));
            tOrderDetailMapper.insertTemplate(detail);
        });
        result.put("details", details);
        if (cartids.size() > 0) {
            tCartMapper.deleteByCartids(me.getMid(), cartids);
        }
        return result;
    }


    /**
     * 我的订单列表
     *
     * @param orderstatus
     * @param curpage
     * @param pagesize
     * @return
     */
    @GetAction("myOrderList.json")
    @With({WbILogin.class})
    public List<JSONObject> myOrderList(String orderstatus, Integer curpage, Integer pagesize) {
        return orderList(true, orderstatus, null, curpage, pagesize);
    }

    /**
     * 客户订单列表
     *
     * @param finishdata
     * @param curpage
     * @param pagesize
     * @return
     */
    @GetAction("customOrderList.json")
    @With({WbILogin.class})
    public List<JSONObject> customOrderList(String finishdata, Integer curpage, Integer pagesize) {
        return orderList(false, null, finishdata, curpage, pagesize);
    }

    /**
     * 查询订单列表并处理数据
     *
     * @param ismine
     * @param orderstatus
     * @param finishdata
     * @param curpage
     * @param pagesize
     * @return
     */
    private List<JSONObject> orderList(Boolean ismine, String orderstatus, String finishdata, Integer curpage, Integer pagesize) {
        String mid = me.getMid();
//        String mid="6ebffa1f44f04b65b67f7165655c4426";
        //查询我的
        List<JSONObject> list;
        if (ismine) {
            list = tOrderMapper.orderList(orderstatus, null, null, mid, curpage * pagesize, pagesize);
        } else {
            list = tOrderMapper.orderList(GlobalValues.ORDER_STATUS_4.value(), finishdata, mid, null, curpage * pagesize, pagesize);
        }
        if (list != null && list.size() > 0) {
            Set<String> set = new HashSet();
            List<JSONObject> result = new ArrayList<>();
            list.forEach(json -> {
                if (set.add(json.getString("orderid"))) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("orderid", json.get("orderid"));
                    jsonObject.put("orderstatus", json.get("orderstatus"));
                    jsonObject.put("mname", json.get("mname"));
                    jsonObject.put("nickname", json.get("nickname"));
                    jsonObject.put("finishdate", json.get("finishdate"));
                    jsonObject.put("totalnum", json.get("detailrnumber"));//总数量
                    jsonObject.put("totalcommission", json.get("commission"));//总佣金
                    jsonObject.put("orderamount", json.get("detailtotal"));//总金额
                    List<JSONObject> subList = new ArrayList<>();
                    subList.add(json);
                    jsonObject.put("sublist", subList);
                    result.add(jsonObject);
                } else {
                    JSONObject lastJson = result.get(result.size() - 1);
                    handleTotal(lastJson, json);
                }
            });
            return result;
        }
        return new ArrayList<>();
    }

    /**
     * 叠加总金额,总数量,总收益
     *
     * @param lastJson
     * @param json
     */
    private void handleTotal(JSONObject lastJson, JSONObject json) {
        lastJson.put("totalnum", lastJson.getIntValue("totalnum") + json.getIntValue("detailrnumber"));
        lastJson.put("totalcommission", lastJson.getBigDecimal("totalcommission").add(json.getBigDecimal("commission")));
        lastJson.put("orderamount", lastJson.getBigDecimal("orderamount").add(json.getBigDecimal("detailtotal")));
        List<JSONObject> skulist = (List<JSONObject>) lastJson.get("sublist");
        skulist.add(json);
    }


    @GetAction("orderDetail.json")
    @With({WbILogin.class})
    public Map<String, Object> orderDetail(String orderid) {
        Map<String, Object> order = tOrderMapper.queryOrder(orderid);
        List<Map<String, Object>> list = tOrderDetailMapper.detailList(orderid);
        order.put("sublist", list);
        return order;
    }

    @PutAction("updateOrderStatus.json")
    @With({WbILogin.class, ITranslate.class})
    /**
     * 3,4,5
     */
    public Integer updateOrderStatus(String orderid, String orderstatus) {
        TOrder order = tOrderMapper.single(orderid);
        TOrder param = new TOrder();
        param.setOrderid(orderid);
        param.setOrderstatus(orderstatus);
        if (S.eq(GlobalValues.ORDER_STATUS_5.value(), orderstatus)) {
            //已取消
            if (S.neq(GlobalValues.ORDER_STATUS_0.value(), order.getOrderstatus())) {
                throw new UserException("订单不是待付款状态,不能取消");
            }
        } else if (S.eq(GlobalValues.ORDER_STATUS_3.value(), orderstatus)) {
            //已发货
            if (S.neq(GlobalValues.ORDER_STATUS_2.value(), order.getOrderstatus())) {
                throw new UserException("订单不是待收货状态,不能收货");
            }
            param.setRevdate(DateUtil.now());
        } else if (S.eq(GlobalValues.ORDER_STATUS_4.value(), orderstatus)) {
            //已完成
            if (S.neq(GlobalValues.ORDER_STATUS_3.value(), order.getOrderstatus())) {
                throw new UserException("订单不是已收货状态,不能完成");
            }
            param.setFinishdate(DateUtil.now());
            tOrderDetailMapper.updateFinishdateByOrderid(orderid,param.getFinishdate());
        }
        return tOrderMapper.updateTemplateById(param);
    }


    @On(value= PayValues.PAT_EVENT_NAME_BUY_PRODUCT)
    public int payBackEvent(ActEvent<Map<String,Object>> event){
        Map<String,Object> param=event.source();
        String orderid=MapUtil.getStr(param,"orderid");
        return this.payBack(orderid);
    }

    @PutAction("payBack.json")
    @With({WbILogin.class, ITranslate.class})
    public int payBack(String orderid) {
        BigDecimal fscale=BigDecimal.ZERO;
        BigDecimal rscale=BigDecimal.ZERO;
        String isfirst="0";
        TOrder tOrder=tOrderMapper.single(orderid);
        // 验证支付状态不是待支付，直接返回
        if(S.neq(tOrder.getOrderstatus(),GlobalValues.ORDER_STATUS_0.value())){
            return 0;
        }
        //查询是否首单
        Integer ocount=tOrderMapper.selectIsFirst(tOrder.getMid());
        if(0<ocount){
            CpConfig config = cpConfigMapper.single(GlobalValues.CP_CONFIG_FSCALE.value());
            fscale=new BigDecimal(config.getCfvalue());
            isfirst="1";
        }else{
            //查询是否有返单奖励
            int mtype=tOrderMapper.selectMebType(tOrder.getMid());
            if(mtype>0){
                CpConfig config = cpConfigMapper.single(GlobalValues.CP_CONFIG_RSCALE.value());
                rscale=new BigDecimal(config.getCfvalue());
            }
            isfirst="0";
        }
        tOrderMapper.updateOrderPay(orderid,tOrder.getPaytype(),fscale,rscale,isfirst);
        //记录支付流水
        TMbOrderFlow tMbOrderFlow = new TMbOrderFlow();
        tMbOrderFlow.setOfid(S2.UUID());
        tMbOrderFlow.setMid(tOrder.getMid());
        tMbOrderFlow.setOrderid(orderid);
        tMbOrderFlow.setPayamount(tOrder.getOrderamount());
        tMbOrderFlow.setPaytype(tOrder.getPaytype());
        tMbOrderFlow.setPayorderno(tOrder.getPaytype());
        tMbOrderFlow.setOfdate(DateUtil.now());
        tMbOrderFlow.setOfflag(GlobalValues.Z_FLOW_OFFLAG_0.value());
        tMbOrderFlowMapper.insert(tMbOrderFlow);
        return 0;
    }
}
